package com.baozheyangken.ai_learn.aspect;

import com.baozheyangken.ai_learn.exception.PermissionInsufficient;
import com.baozheyangken.ai_learn.exception.PermissionNotRequestMapping;
import com.baozheyangken.ai_learn.pojo.entity.Permission;
import com.baozheyangken.ai_learn.pojo.entity.User;
import com.baozheyangken.ai_learn.pojo.result.Result;
import com.baozheyangken.ai_learn.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Aspect
@Component
@Slf4j
public class PermissionAspect {

    private static final List<String> authWhiteList = List.of(new String[]{"register", "login"});

    private static final String logDefault = "Aspect: ";

    @Autowired
    private UserService userService;

    //拦截所有Controller包下的所有包含@RequiresAuthentication注解的类
    @Pointcut("within(@com.baozheyangken.ai_learn.annotation.RequiresAuthentication *) &&" +
            "execution(* com.baozheyangken.ai_learn.controller..*(..))")
    public void nonAuthenticatedControllerMethods() {
    }

    @Around("nonAuthenticatedControllerMethods()")
    public Object logMethodAccess(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getName();
        log.info("{}当前执行的类：{}，方法：{}", logDefault, className, methodName);

        //放行点1
        if (authWhiteList.contains(methodName))
            return joinPoint.proceed();

        //获取当前用户的权限表：
        List<String> permissionList = userService.userPermission();
        log.info("{}当前用户的权限列表:{}", logDefault, permissionList);

        //获取类中@RequestMapping注解参数
        Class<?> targetClass = joinPoint.getTarget().getClass();
        RequestMapping requestMapping = targetClass.getAnnotation(RequestMapping.class);
        if (requestMapping != null) {
            String[] classPaths = requestMapping.value();
            log.info("{}类上的 RequestMapping路径：{}", logDefault, Arrays.toString(classPaths));
            //放行点2
            if (permissionList.contains(classPaths[0]))
                return joinPoint.proceed();
            else throw new PermissionInsufficient();
        } else
            throw new PermissionNotRequestMapping();
    }

}
